// api/handlers/test_handler.go
package handlers

import (
	"mygin/internal/models"
	"mygin/internal/services"
	"net/http"
	"strconv"

	"mygin/pkg/response"

	"github.com/gin-gonic/gin"
)

type TestHandler struct {
	service *services.TestService
}

func NewTestHandler(service *services.TestService) *TestHandler {
	return &TestHandler{service: service}
}

// @Summary 创建
// @Description 创建数据
// @Tags Test管理
// @Accept json
// @Produce json
// @Param test body models.TestCreateRequest true "信息"
// @Example request {"name": "john_doe", "age": "12"}
// @Success 200 {object} models.Test"创建成功"
// @Failure 400 {object} response.ErrorResponse "请求参数错误"
// @Failure 500 {object} response.ErrorResponse "服务器内部错误"
// @Router /api/v1/tests [post]
func (h *TestHandler) CreateTest(c *gin.Context) {
	var test models.Test
	if err := c.ShouldBindJSON(&test); err != nil {
		c.JSON(http.StatusBadRequest, response.Fail(400, err.Error()))
		return
	}

	if err := h.service.RegisterTest(&test); err != nil {
		c.JSON(http.StatusBadRequest, response.Fail(400, err.Error()))
		return
	}

	c.JSON(http.StatusOK, response.Success("success", test))
}

// GetTest 获取用户信息
// @Summary 通过ID获取用户信息(V1)
// @Description 根据用户ID获取详细的用户信息
// @Tags Test管理
// @Accept json
// @Produce json
// @Param id path int true "用户ID" Format(uint64)
// @Success 200 {object} models.Test
// @Failure 400 {object} response.ErrorResponse "无效的ID格式或用户不存在"
// @Router /api/v1/tests/{id} [get]
func (h *TestHandler) GetTest(c *gin.Context) {
	idStr := c.Param("id")

	// 将字符串ID转换为uint
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil {
		c.JSON(http.StatusBadRequest, response.Fail(400, "参数不对"))
		return
	}

	// 调用服务层
	test, err := h.service.GetTestByID(uint(id))
	if err != nil {
		c.JSON(http.StatusBadRequest, response.Fail(400, "test not found"))
		return
	}
	c.JSON(http.StatusOK, response.Success("success", test))
}

// @Summary 获取列表(V1)
// @Description 获取分页列表
// @Tags  Test管理
// @Accept json
// @Produce json
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(10)
// @Param name query string false "名称"
// @Param age query string false "年龄筛选"
// @Failure 400 {object} map[string]string "参数错误"
// @Failure 500 {object} map[string]string "内部错误"
// @Router /api/v1/tests [get]
func (h *TestHandler) ListTests(c *gin.Context) {
	// 获取分页参数
	page, err := strconv.Atoi(c.DefaultQuery("page", "1"))
	if err != nil || page < 1 {
		c.JSON(http.StatusBadRequest, response.Fail(400, "页面参数无效"))
		return
	}

	pageSize, err := strconv.Atoi(c.DefaultQuery("page_size", "10"))
	if err != nil || pageSize < 1 {
		c.JSON(http.StatusBadRequest, response.Fail(400, "page_size参数无效"))
		return
	}

	// 获取筛选条件
	filter := services.TestFilter{
		Name: c.Query("name"),
		Age:  c.Query("age"),
	}

	// 调用服务层获取用户列表和总数
	tests, total, err := h.service.ListTests(page, pageSize, filter)
	if err != nil {
		c.JSON(http.StatusBadRequest, response.Fail(400, err.Error()))
		return
	}

	// 使用公共分页响应
	c.JSON(http.StatusOK, response.Success("success", response.NewPaginationResponse(total, page, pageSize, tests)))
}

// UpdateTest 更新用户信息
// @Summary 更新用户信息(V1)
// @Tags  Test管理
// @Param id path int true "用户ID"
// @Param test body models.TestCreateRequest true "用户更新数据"
// @Success 200 {object} models.Test
// @Router /api/v1/tests/{id} [put]
func (h *TestHandler) UpdateTest(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil {
		c.JSON(http.StatusBadRequest, response.Fail(400, "ID格式无效"))
		return
	}

	// 根据HTTP方法决定是全量还是部分更新
	if c.Request.Method == http.MethodPut {
		// PUT - 全量更新
		var test models.Test
		if err := c.ShouldBindJSON(&test); err != nil {
			c.JSON(http.StatusBadRequest, response.Fail(400, err.Error()))
			return
		}
		test.ID = uint(id)
		err = h.service.UpdateTest(&test)
	} else {
		// PATCH - 部分更新
		var updateData map[string]interface{}
		if err := c.ShouldBindJSON(&updateData); err != nil {
			c.JSON(http.StatusBadRequest, response.Fail(400, err.Error()))
			return
		}
		err = h.service.UpdatePartial(uint(id), updateData)
	}

	if err != nil {
		c.JSON(http.StatusBadRequest, response.Fail(400, err.Error()))
		return
	}
	c.JSON(http.StatusOK, response.Success("success", ""))
}

// @Summary 删除(V1)
// @Tags  Test管理
// @Description 删除(软删除)
// @Param id path int true "ID"
// @Success 200 {object} models.Test "成功返回"
// @Failure 400 {object} map[string]string "参数错误"
// @Router /api/v1/tests/{id} [delete]
func (h *TestHandler) DeleteTest(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 64)
	if err != nil {
		c.JSON(http.StatusBadRequest, response.Fail(400, "ID格式无效"))
		return
	}

	if err := h.service.DeleteTest(uint(id)); err != nil {
		switch err.Error() {
		case "test not found":
			c.JSON(http.StatusBadRequest, response.Fail(400, err.Error()))
		default:
			c.JSON(http.StatusBadRequest, response.Fail(400, err.Error()))
		}
		return
	}
	c.JSON(http.StatusOK, response.Success("success", ""))
}

/**************非curd方法区************************************/

// @Summary 通过用户名获取用户信息
// @Description 根据用户名获取详细的用户信息
// @Tags Test管理
// @Accept json
// @Produce json
// @Param testname path string true "用户名"
// @Success 200 {object} models.Test
// @Failure 400 {object} response.ErrorResponse "无效的用户名"
// @Failure 404 {object} response.ErrorResponse "用户不存在"
// @Router /api/v1/tests/testname/{testname} [get]
func (h *TestHandler) GetTestByTestname(c *gin.Context) {
	testname := c.Param("testname")
	if testname == "" {
		c.JSON(http.StatusBadRequest, response.Fail(http.StatusBadRequest, "testname cannot be empty"))
		return
	}

	test, err := h.service.GetTestByTestname(testname)
	if err != nil {
		c.JSON(http.StatusNotFound, response.Fail(http.StatusNotFound, "test not found"))
		return
	}

	c.JSON(http.StatusOK, response.Success("success", test))
}
